package com.supermap.wzhy.data;

import com.supermap.wzhy.module.fr.service.FrPushDataToMlkService;
import com.supermap.wzhy.module.fr.service.FrWjgService;
import com.supermap.wzhy.module.mlk.service.MlkPushDataToFrService;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;

import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Set;

/**
 * Created by sun'fei on 17-2-21.
 */
public class QuartzManager {

    private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
    private static String JOB_GROUP_NAME = "WZHY_QUARTZ_JOB";
    private static String TRIGGER_GROUP_NAME = "WZHY_TRIGGER";

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    /**
     * 添加一个定时任务，使用默认的任务组名，触发器名，触发器组名
     * @param jobName 自定义定时任务名
     * @param jobClass 定时任务类
     * @param time 定时时间(参考quartz文档时间设置)
     * @param map 定时任务参数
     * @param service 定时任务需要注入的service
     */
    public static void addJob(String jobName, Class jobClass, String time,Map map,FrPushDataToMlkService service) {
        try {
            //先尝试移除当前任务名的定时任务
            boolean boo = removeJob(jobName);
            if(boo){
                System.out.println("已移除上一个 "+jobName+" 定时任务");
            }else{
                System.out.println("没有定时任务");
            }
            //得到调度器
            Scheduler sched = gSchedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobName, jobClass);// 任务名，任务组，任务执行类

            //传入参数
            if(!map.isEmpty()){
                Object [] key = map.keySet().toArray();
                for(int i = 0;i < key.length;i++){
                    jobDetail.getJobDataMap().put(key[i].toString(),map.get(key[i]));
                }
            }

            //注入service放入job上下文中
            jobDetail.getJobDataMap().put("service",service);

            // 触发器 触发任务调度器
            // 调度器 调度当前定时任务执行命令
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger); //调度任务
            // 启动调度器
            if (!sched.isShutdown()){
                sched.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void addMLkToFrkJob(String jobName, Class jobClass, String time,Map map,MlkPushDataToFrService service) {
        try {
            //先尝试移除当前任务名的定时任务
            boolean boo = removeJob(jobName);
            if(boo){
                System.out.println("已移除上一个 "+jobName+" 定时任务");
            }else{
                System.out.println("没有定时任务");
            }

            Scheduler sched = gSchedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobName, jobClass);// 任务名，任务组，任务执行类

            //传入参数
            if(!map.isEmpty()){
                Set set = map.keySet();
                Object [] key = set.toArray();
                for(int i = 0;i < key.length;i++){
                    jobDetail.getJobDataMap().put(key[i].toString(),map.get(key[i]));
                }
            }

            jobDetail.getJobDataMap().put("service",service);

            // 触发器 调度需要自动执行的任务
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown()){
                sched.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void addFrToMlkJob(String jobName, Class jobClass, String time,Map map,
                                     FrPushDataToMlkService service) {
        try {
            //先尝试移除当前任务名的定时任务
            boolean boo = removeJob(jobName);
            if(boo){
                System.out.println("已移除上一个 "+jobName+" 定时任务");
            }else{
                System.out.println("没有定时任务");
            }

            Scheduler sched = gSchedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobName, jobClass);// 任务名，任务组，任务执行类

            //传入参数
            if(!map.isEmpty()){
                Set set = map.keySet();
                Object [] key = set.toArray();
                for(int i = 0;i < key.length;i++){
                    jobDetail.getJobDataMap().put(key[i].toString(),map.get(key[i]));
                }
            }

            jobDetail.getJobDataMap().put("service",service);
/*
            if(delayedDate != null){
                SimpleTrigger simpleTrigger = new SimpleTrigger(simpleDateFormat.format(delayedDate)+jobName,
                        simpleDateFormat.format(delayedDate)+TRIGGER_GROUP_NAME);

                simpleTrigger.setStartTime(delayedDate);
                sched.scheduleJob(jobDetail,simpleTrigger);
                if (!sched.isShutdown()){
                    sched.start();
                }
                return;
            }*/
            // 触发器
            // 调度器 调度当前定时任务执行命令
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组

            trigger.setCronExpression(time);// 触发器时间设定

            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown()){
                sched.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void addWjgJob(String jobName, Class jobClass, String time,Map map,FrWjgService service) {
        try {

            //先尝试移除当前任务名的定时任务
            boolean boo = removeJob(jobName);
            if(boo){
                System.out.println("已移除上一个 "+jobName+" 定时任务");
            }else{
                System.out.println("没有定时任务");
            }

            Scheduler sched = gSchedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobName, jobClass);// 任务名，任务组，任务执行类

            //传入参数
            if(!map.isEmpty()){
                Set set = map.keySet();
                Object [] key = set.toArray();
                for(int i = 0;i < key.length;i++){
                    jobDetail.getJobDataMap().put(key[i].toString(),map.get(key[i]));
                }
            }

            jobDetail.getJobDataMap().put("service",service);

            // 触发器
            // 调度器 调度当前定时任务执行命令
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
            // 启动
            if (!sched.isShutdown()){
                sched.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加一个定时任务
     *
     * @param jobName
     *            任务名
     * @param jobGroupName
     *            任务组名
     * @param triggerName
     *            触发器名
     * @param triggerGroupName
     *            触发器组名
     * @param jobClass
     *            任务
     * @param time
     *            时间设置，参考quartz说明文档
     */
    public static void addJob(String jobName, String jobGroupName,
                              String triggerName, String triggerGroupName, String jobClass, String time){
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            JobDetail jobDetail = new JobDetail(jobName, jobGroupName, Class.forName(jobClass));// 任务名，任务组，任务执行类
            // 触发器
            CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
            trigger.setCronExpression(time);// 触发器时间设定
            sched.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改一个任务的触发时间(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param jobName
     * @param time
     */
    public static void modifyJobTime(String jobName, String time,FrPushDataToMlkService service) {
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
            if(trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time)) {
                JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);
                Class objJobClass = jobDetail.getJobClass();
                Map map = jobDetail.getJobDataMap();
                //String jobClass = objJobClass.getName();
                removeJob(jobName);

                addJob(jobName, objJobClass, time,map,service);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 修改一个任务的触发时间
     *
     * @param triggerName
     * @param triggerGroupName
     * @param time
     */
    public static void modifyJobTime(String triggerName,
                                     String triggerGroupName, String time) {
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);
            if(trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time)) {
                CronTrigger ct = (CronTrigger) trigger;
                // 修改时间
                ct.setCronExpression(time);
                // 重启触发器
                sched.resumeTrigger(triggerName, triggerGroupName);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 移除一个任务(根据任务名和默认的任务组名，触发器名，触发器组名删除一个任务)
     *
     * @param jobName
     */
    public static boolean removeJob(String jobName) {
        boolean boo = false;
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
            sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
            sched.deleteJob(jobName, jobName);// 删除任务
            System.out.println("已停止 "+jobName+" 定时任务");
            boo = true;
            return boo;
        } catch (Exception e) {
            boo = false;
            System.out.println("停止 "+jobName+" 定时任务异常");
        }finally {
            return boo;
        }
    }

    /**
     * 移除一个任务
     *
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    public static void removeJob(String jobName, String jobGroupName,
                                 String triggerName, String triggerGroupName) {
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器
            sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器
            sched.deleteJob(jobName, jobGroupName);// 删除任务
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 启动所有定时任务
     */
    public static void startAllJobs() {
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            sched.start();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    /**
     * 关闭所有定时任务
     */
    public static void shutdownAllJobs() {
        try {
            Scheduler sched = gSchedulerFactory.getScheduler();
            if(!sched.isShutdown()) {
                sched.shutdown();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}
